package org.tis.tools.abf.module.ac.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.tis.tools.abf.module.ac.controller.request.AcDeleteListRequest;
import org.tis.tools.abf.module.ac.dao.AcFuncMapper;
import org.tis.tools.abf.module.ac.entity.*;
import org.tis.tools.abf.module.ac.entity.enums.FuncType;
import org.tis.tools.abf.module.ac.exception.AcExceptionCodes;
import org.tis.tools.abf.module.ac.exception.AcManagementException;
import org.tis.tools.abf.module.ac.service.*;
import org.tis.tools.abf.module.common.entity.enums.YON;
import org.tis.tools.core.utils.StringUtil;
import org.tis.tools.model.enums.IRequestMethod;

import java.math.BigDecimal;
import java.util.List;

import static org.tis.tools.core.utils.BasicUtil.wrap;

/**
 * acFunc的Service接口实现类
 *
 * @author Auto Generate Tools
 * @date 2018/04/23
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class AcFuncServiceImpl extends ServiceImpl<AcFuncMapper, AcFunc> implements IAcFuncService {

    @Autowired
    IAcFuncService acFuncService;
    @Autowired
    private IAcFuncAttrService acFuncAttrService;
    @Autowired
    private IAcRoleFuncService acRoleFuncService;
    @Autowired
    private IAcOperatorFuncService acOperatorFuncService;
    @Autowired
    private IAcMenuService acMenuService;


    /**
     * 新增功能行为
     */
    @Override
    public AcFunc creatFunc(String guidApp, FuncType funcType, String funcCode, String funcName, String displayOrder, String funcDesc, String guidFunc,YON isopen,YON ischeck,String uiEntry,String serviceEntry) throws AcManagementException {

        if (StringUtil.isNotEmpty(serviceEntry)){
            String requestHead = serviceEntry.substring(0,serviceEntry.indexOf("/"));
            IRequestMethod iRequestMethod = IRequestMethod.matchRequestMethod(requestHead);
            if (null == iRequestMethod){
                throw new AcManagementException(AcExceptionCodes.PATH_PARAMETER_IS_EXIST);
            }
        }

        AcFunc acFunc = new AcFunc();

       if (null == isopen){
           isopen = YON.YES;
       }

       if (null == ischeck){
           ischeck = YON.YES;
       }

        Integer queryOrder = this.baseMapper.getMaxOrder();
        /** 避免数据库没有数据的时候查询出来的结构为null */
        if (null == queryOrder){
            queryOrder = -1;
        }
        BigDecimal displayOrderNew =  BigDecimal.valueOf(queryOrder+1);

        //收集参数
        acFunc.setGuidApp(guidApp);
        acFunc.setFuncCode(funcCode);
        acFunc.setFuncType(funcType);
        acFunc.setFuncName(funcName);
        acFunc.setDisplayOrder(displayOrderNew);
        acFunc.setFuncDesc(funcDesc);
        acFunc.setGuidFunc(guidFunc);
        acFunc.setUiEntry(uiEntry);
        acFunc.setServiceEntry(serviceEntry);

        //默认为需要验证
        acFunc.setIscheck(ischeck);
        //默认为应用启用
        acFunc.setIsopen(isopen);

        //新增
        acFuncService.insert(acFunc);
        return acFunc;
    }

    /**
     * 修改功能行为
     */
    @Override
    public AcFunc changeFunc(String guid, String guidApp, FuncType funcType, String funcCode, String funcName, String funcDesc, YON isopen, YON ischeck, String displayOrder, String guidFunc,String uiEntry,String serviceEntry) throws AcManagementException {

        if (StringUtil.isNotEmpty(serviceEntry)){
            String requestHead = serviceEntry.substring(0,serviceEntry.indexOf("/"));
            IRequestMethod iRequestMethod = IRequestMethod.matchRequestMethod(requestHead);
            if (null == iRequestMethod){
                throw new AcManagementException(AcExceptionCodes.PATH_PARAMETER_IS_EXIST);
            }
        }

        AcFunc acFunc = new AcFunc();

        BigDecimal disPlayOrderNew = BigDecimal.valueOf(Double.valueOf(displayOrder));

        acFunc.setGuid(guid);
        acFunc.setGuidApp(guidApp);
        acFunc.setFuncType(funcType);
        acFunc.setFuncCode(funcCode);
        acFunc.setFuncName(funcName);
        acFunc.setFuncDesc(funcDesc);
        acFunc.setGuidFunc(guidFunc);
        acFunc.setDisplayOrder(disPlayOrderNew);
        acFunc.setIsopen(isopen);
        acFunc.setIscheck(ischeck);
        acFunc.setUiEntry(uiEntry);
        acFunc.setServiceEntry(serviceEntry);

        //修改
        acFuncService.updateById(acFunc);
        return acFunc;
    }

    /**
     * 查询对应应用下的功能
     */
    @Override
    public Page<AcFunc> queryPageById(Page<AcFunc> page, Wrapper<AcFunc> wrapper, String id) throws AcManagementException {

        Page<AcFunc> pagefunc = null;

        if (null == wrapper){
            wrapper = new EntityWrapper<AcFunc>();
        }

        wrapper.eq(AcFunc.COLUMN_GUID_APP,id);
        pagefunc = acFuncService.selectPage(page,wrapper);
        return pagefunc;
    }


    @Override
    public List<AcFunc> queryAll() throws AcManagementException {
        Wrapper<AcFunc> wrapper = new EntityWrapper<AcFunc>();
        wrapper.eq(AcFunc.COLUMN_FUNC_TYPE,FuncType.FUNCTION);
        return selectList(wrapper);
    }

    /**
     * 查询功能下所有行为(分页)
     */
    @Override
    public Page<AcFunc> pageQueryBehaveByFuncId(Page<AcFunc> page, Wrapper<AcFunc> wrapper, String funcId) throws AcManagementException {

        if (null == wrapper){
            wrapper = new EntityWrapper<AcFunc>();
        }

        wrapper.eq(AcFunc.COLUMN_GUID_FUNC,funcId);
        wrapper.eq(AcFunc.COLUMN_FUNC_TYPE,FuncType.BEHAVE);

        return selectPage(page,wrapper);
    }

    /**
     * 根据应用ID查询功能
     */
    @Override
    public Page<AcFunc> pageQueryFuncByAppId(Page<AcFunc> page, Wrapper<AcFunc> wrapper, String appId) throws AcManagementException {

        if (null == wrapper){
            wrapper = new EntityWrapper<AcFunc>();
        }

        wrapper.eq(AcFunc.COLUMN_GUID_APP,appId);
        wrapper.eq(AcFunc.COLUMN_FUNC_TYPE,FuncType.FUNCTION);
        wrapper.orderBy(AcFunc.COLUMN_DISPLAY_ORDER,true);
        wrapper.orderBy(AcFunc.COLUMN_FUNC_CODE,true);

        return selectPage(page,wrapper);
    }

    @Override
    public void moveFunc(String id) throws AcManagementException {

        //确认该功能是否可删除
        if (!confirmFuncDeleted(id)){
             throw new AcManagementException(AcExceptionCodes.FAILURE_WHRN_DELETE_AC_FUNC);
        }

        //查询出功能属性
        Wrapper<AcFuncAttr> wrapperAttr = new EntityWrapper<AcFuncAttr>();
        wrapperAttr.eq(AcFuncAttr.COLUMN_GUID_FUNC,id);
        List<AcFuncAttr> listAttr = acFuncAttrService.selectList(wrapperAttr);
        if (0 != listAttr.size()){
            //删除功能属性
            acFuncAttrService.delete(wrapperAttr);
        }

        //查询出权限集(角色)功能对应关系信息
        Wrapper<AcRoleFunc> wrapperRole = new EntityWrapper<AcRoleFunc>();
        wrapperRole.eq(AcRoleFunc.COLUMN_GUID_FUNC,id);
        List<AcRoleFunc> listRole = acRoleFuncService.selectList(wrapperRole);
        if (0 != listRole.size()){
            //删除权限集(角色)功能数据
            for (AcRoleFunc acRoleFunc : listRole){
                if (null != acRoleFunc){
                    acRoleFuncService.deleteRoleFunc(acRoleFunc.getGuid());
                }
            }
        }

        //查询出操作员特殊权限配置信息
        Wrapper<AcOperatorFunc> wrapperOper = new EntityWrapper<AcOperatorFunc>();
        wrapperOper.eq(AcOperatorFunc.COLUMN_GUID_FUNC,id);
        List<AcOperatorFunc> listOper = acOperatorFuncService.selectList(wrapperOper);
        if (0 != listOper.size()){
            //删除操作员特殊权限配置数据
            for (AcOperatorFunc acOperatorFunc : listOper){
                if (null != acOperatorFunc){
                    acOperatorFuncService.deleteOperatorFunc(acOperatorFunc.getGuid());
                }
            }
        }

        //删除功能
        deleteById(id);
    }

    /**
     * 批量删除功能行为
     */
    @Override
    public void moveBatchFunc(AcDeleteListRequest listRequest) throws AcManagementException {

        if (0 == listRequest.getDeleteList().size()){
            throw new AcManagementException(AcExceptionCodes.PARAMETER_IS_EMPTY_WHRN_BATCH_DELETE,wrap("删除时参数列表为空"));
        }

        for (String funcGuid : listRequest.getDeleteList()){
            if (!StringUtil.isEmpty(funcGuid)){
                AcFunc acFunc = selectById(funcGuid);
                if (null == acFunc){
                    throw new AcManagementException(AcExceptionCodes.FAILURE_WHRN_QUERY_AC_NULL,wrap
                            ("删除的列表中有不存在或已删除的功能或行为！"));
                }
            }
        }

        for(String funcGuid : listRequest.getDeleteList()){
            if (!StringUtil.isEmpty(funcGuid)){
                moveFunc(funcGuid);
            }
        }

    }

    @Override
    public List<AcFunc> queryFuncTreeByApp(String appId) throws AcManagementException {

        Wrapper<AcFunc> funcWrapper = new EntityWrapper<AcFunc>();
        funcWrapper.eq(AcFunc.COLUMN_GUID_APP,appId);
        funcWrapper.isNull(AcFunc.COLUMN_GUID_FUNC);
        funcWrapper.eq(AcFunc.COLUMN_FUNC_TYPE,FuncType.FUNCTION);

        List<AcFunc> funcList = selectList(funcWrapper);
        return funcList;
    }

    /**
     * 根据应用和父功能下的子功能查询功能列表
     */
    @Override
    public List<AcFunc> queryFuncTreeByAppFunc(String appId, String funcId) throws AcManagementException {

        Wrapper<AcFunc> wrapper = new EntityWrapper<AcFunc>();
        wrapper.eq(AcFunc.COLUMN_GUID_APP,appId);
        wrapper.eq(AcFunc.COLUMN_GUID_FUNC,funcId);
        wrapper.eq(AcFunc.COLUMN_FUNC_TYPE,FuncType.FUNCTION);

        List<AcFunc> list = selectList(wrapper);
        return list;
    }

    /**
     * 根据应用和功能查询行为列表
     */
    @Override
    public List<AcFunc> queryBehaveTreeByAppFunc(String appId, String funcId) throws AcManagementException {
        Wrapper<AcFunc> wrapper = new EntityWrapper<AcFunc>();
        wrapper.eq(AcFunc.COLUMN_GUID_APP,appId);
        wrapper.eq(AcFunc.COLUMN_GUID_FUNC,funcId);
        wrapper.eq(AcFunc.COLUMN_FUNC_TYPE,FuncType.BEHAVE);

        List<AcFunc> list = selectList(wrapper);
        return list;
    }

    /**
     * 确认该功能是否可删除
     * 功能正在被菜单引用
     * 功能分配给了角色
     * 功能作为特殊权限分配给了操作员
     */
    @Override
    public Boolean confirmFuncDeleted(String deleteGuid) throws AcManagementException {

        Boolean cannotDelete = true;

        if (StringUtil.isEmpty(deleteGuid)){
            throw new AcManagementException(AcExceptionCodes.PARMS_NOT_ALLOW_EMPTY);
        }

            AcFunc acFunc = null;
            if (null != deleteGuid){
                Wrapper<AcFunc> funcWrapper = new EntityWrapper<AcFunc>();
                funcWrapper.eq(AcFunc.COLUMN_GUID,deleteGuid);
                funcWrapper.eq(AcFunc.COLUMN_FUNC_TYPE,FuncType.FUNCTION);
                acFunc = selectOne(funcWrapper);
            }

            if (null != acFunc){
                //功能是否被菜单引用
                Wrapper<AcMenu> menuWrapper = new EntityWrapper<AcMenu>();
                menuWrapper.eq(AcMenu.COLUMN_GUID_FUNC,deleteGuid);
                List<AcMenu> menuList = acMenuService.selectList(menuWrapper);
                if (0 != menuList.size()){
                    cannotDelete = false;
                    throw new AcManagementException(AcExceptionCodes.NOT_DELETE_WHEN_AC_FUNC_IN_AC_MENU);
                }

                //功能分配给了角色
                Wrapper<AcRoleFunc> roleFuncWrapper = new EntityWrapper<AcRoleFunc>();
                roleFuncWrapper.eq(AcRoleFunc.COLUMN_GUID_FUNC,deleteGuid);
                List<AcRoleFunc> roleFuncList = acRoleFuncService.selectList(roleFuncWrapper);
                if (0 != roleFuncList.size()){
                    cannotDelete = false;
                    throw new AcManagementException(AcExceptionCodes.NOT_DELETE_WHEN_AC_FUNC_IN_AC_ROLE_FUNC);
                }

                //功能作为特殊权限分配给了操作员
                Wrapper<AcOperatorFunc> operatorFuncWrapper = new EntityWrapper<AcOperatorFunc>();
                operatorFuncWrapper.eq(AcOperatorFunc.COLUMN_GUID_FUNC,deleteGuid);
                List<AcOperatorFunc> operatorFuncList = acOperatorFuncService.selectList(operatorFuncWrapper);
                if (0 != operatorFuncList.size()){
                    cannotDelete = false;
                    throw new AcManagementException(AcExceptionCodes.NOT_DELETE_WHEN_AC_FUNC_IN_AC_OPERATOR_FUNC);
                }
            }
        return cannotDelete;
    }

    /**
     * 开通功能
     */
    @Override
    public AcFunc openFunc(AcFunc acFunc) throws AcManagementException {

        if (YON.YES.toString().equals(acFunc.getIsopen().toString())){
            throw new AcManagementException(AcExceptionCodes.AC_FUNC_YES_IS_OPEN);
        }
        acFunc.setIsopen(YON.YES);
        updateById(acFunc);
        return acFunc;
    }

    /**
     * 停用功能
     */
    @Override
    public AcFunc closeFunc(AcFunc acFunc) throws AcManagementException {

        if (YON.NO.toString().equals(acFunc.getIsopen().toString())){
            throw new AcManagementException(AcExceptionCodes.AC_FUNC_NO_IS_OPEN);
        }
        acFunc.setIsopen(YON.NO);
        updateById(acFunc);
        return acFunc;
    }

    /**
     * 根据应用ID查询功能
     */
    @Override
    public List<AcFunc> queryFuncByApp(String guidApp) throws AcManagementException {

        Wrapper<AcFunc> wrapper = new EntityWrapper<AcFunc>();
        wrapper.eq(AcFunc.COLUMN_GUID_APP,guidApp);
        wrapper.eq(AcFunc.COLUMN_FUNC_TYPE,FuncType.FUNCTION);
        wrapper.eq(AcFunc.COLUMN_ISOPEN,YON.YES);

        List<AcFunc> list = selectList(wrapper);

        return list;
    }

    /**
     * 判断行为接口路径参数是否已经存在
     *
     * @param guid          功能GUID
     * @param serviceEntry 路径参数
     * @return 是否存在, false-不存在 true-存在
     */
    @Override
    public Boolean existPathParameter(String guid, String serviceEntry) throws AcManagementException {

        Wrapper<AcFunc> wrapper = new EntityWrapper<>();
        wrapper.eq(AcFunc.COLUMN_SERVICE_ENTRY,serviceEntry);
        List<AcFunc> funcs = selectList(wrapper);

        if (0 != funcs.size()){
            if (StringUtil.isNotEmpty(guid)){
                AcFunc acFunc = selectById(guid);
                if (null == acFunc){
                    throw new AcManagementException(AcExceptionCodes.FAILURE_WHRN_QUERY_AC_FUNC);
                }
                funcs.remove(acFunc);
                if (0 != funcs.size()){
                    return true;
                }
            }else {
                return true;
            }
        }

        return false;
    }

    /**
     * 对外服务提供接口
     * 根据应用获取功能和行为
     */
    @Override
    public List<AcFunc> getFuncBehave(String appId) throws AcManagementException {
        return this.baseMapper.getFuncBehaveByApp(appId);
    }
}

